//
//  HSYBaseModel.h
//  高仿暴走斗图
//
//  Created by huangsongyao on 16/3/4.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import <ReactiveViewModel/ReactiveViewModel.h>

typedef NS_ENUM(NSUInteger, kShareStatusType) {
    
    kShareStatusTypeSuccess     = 1 ,       //分享成功
    kShareStatusTypeFiles       = -1 ,      //分享失败
};

@interface HSYBaseModel : RVMViewModel

@property (nonatomic, strong) NSMutableArray *datas;                    //数据源
@property (nonatomic, strong) id objectPoint;                           //用于数据监听，指向任意对象的指针
@property (nonatomic, strong) RACCommand *command;                      //响应信号
@property (nonatomic, strong) RACSignal *signal;                        //信号，备用
@property (nonatomic, strong) RACSubject *subject;                      //订阅信号，备用

/**
 *  创建button的command信号
 *
 *  @param signal RACCommand响应的RACSignal
 *
 *  @return RACCommand对象
 */
- (RACCommand *)createCommandWithSignal:(RACSignal *)signal;

/**
 *  创建button的command信号对应的RACSignal
 *
 *  @param signals     监听集合: @[RACObserve(self, tream)]
 *  @param reduceBlock 结果回调
 *
 *  @return RACSignal
 */
- (RACSignal *)createRACSignals:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock;

/**
 *  rac遍历数组
 *
 *  @param array        数组对象
 *  @param block        遍历的回调，block，元素对象
 *  @param completed    遍历结束的回调
 */
- (void)rac_traverseArray:(NSArray *)array nextBlock:(void(^)(id x, NSInteger index))block completed:(void(^)(void))completed;

/**
 *  rac遍历字典
 *
 *  @param dictionary 字典对象
 *  @param block      遍历的回调，block，键值对
 *  @param completed  遍历结束的回调
 */
- (void)rac_traverseDictionary:(NSDictionary *)dictionary nextBlock:(void(^)(NSString *key, NSString *value))block completed:(void(^)(void))completed;

/**
 *  rac遍历数组
 *
 *  @param array 要遍历的数组
 *
 *  @return 遍历内容的signal回调
 */
+ (RACSignal *)rac_traverseArray:(NSArray *)array;

/**
 *  rac遍历数组
 *
 *  @param array        数组对象
 *  @param block        遍历的回调，block，元素对象
 *  @param completed    遍历结束的回调
 */
+ (void)rac_traverseArray:(NSArray *)array nextBlock:(void(^)(id x, NSInteger index))block completed:(void(^)(void))completed;

/**
 *  rac遍历字典
 *
 *  @param dictionary 字典对象
 *  @param block      遍历的回调，block，键值对
 *  @param completed  遍历结束的回调
 */
+ (void)rac_traverseDictionary:(NSDictionary *)dictionary nextBlock:(void(^)(NSString *key, NSString *value))block completed:(void(^)(void))completed;

/**
 *  rac遍历字典
 *
 *  @param dictionary 字典对象
 *
 *  @return 遍历内容的signal回调
 */
+ (RACSignal *)rac_traverseDictionary:(NSDictionary *)dictionary;

/**
 *  数组的遍历判断
 *
 *  @param array 要遍历的数组
 *  @param flier 过滤判断的block
 *  @param map   满足判断条件后映射的block
 *
 *  @return 遍历内容的signal回调
 */
+ (RACSequence *)rac_traverseArray:(NSArray *)array filerBlock:(BOOL(^)(id x))flier mapBlock:(id(^)(id x))map;
- (RACSequence *)rac_traverseArray:(NSArray *)array filerBlock:(BOOL(^)(id x))flier mapBlock:(id(^)(id x))map;

/**
 *  rac计时器
 *
 *  @param block 回调计时器时间
 */
- (void)rac_starTimerWithNextBlock:(void(^)(id x))block;

/**
 *  停止rac计时器
 */
- (void)rac_stopTimer;

/**
 监听objectPoint

 @param object 当objectPoint指针所指向的和object这个对象一致时,监听不触发,相当于吞噬掉这个信号
 @param next 监听到objectPoint指针变化时，但是并不包含objectPoint指针变化的对象和object一致时，将会触发次回调
 */
- (void)rac_ignoreObject:(id)object observeSubscribeNext:(void(^)(id value))next;

/**
 监听objectPoint，把objectPoint映射为一个NSNumber类型回调监听

 @param completed 监听条件，即：当满足completed代码块中的条件时，截断信息传递
 @param next 监听回调，获取到一个NSNumber类型的数据
 */
- (void)rac_takeUntilCompleted:(BOOL(^)(id predicate))completed toMap:(id(^)(id value))map observeSubscribeNext:(void(^)(NSNumber *value))next;

/**
 过滤datas数组

 @param completed 过滤条件，此block会被触发数组的count次，并且根据返回的布尔值（YES表示通过信号，NO表示吞噬信号），判断是否触发map
 @param map 映射，用于对datas数组的数据进行映射处理，即：当回调被触发，表示datas数组的当前元素满足条件，时，允许使用map回调一个映射的对象
 @return RACSignal信号
 */
- (RACSignal *)rac_filterUntilCompleted:(BOOL(^)(id predicate))completed toMap:(id(^)(id value))map;

/**
 信号混合和信号重组，next回调次数为signals中的若干信号源的最小信号触发次数

 @param signals 信号集合，格式：@[signalA, signalB, signalC, ...]
 @param reduce 信号内容重组，reduce会对signals中的若干信号源进行重组，然后返回重组后的数据，格式为： reduce:^id(id value1, id value2, ....){return object;}
 @return RACSignal信号
 */
- (RACSignal *)rac_zipSignals:(NSArray <RACSignal *>*)signals reduce:(id(^)())reduce;

/**
 合并两个信号源，会对两个信号源的信号进行一一匹配合并，就像拉链一样，如果把信号源比喻为数组，那各个信号就是index依次递增的元素，此时对两个信号源进行index相同的信号进行合并输入，并且输出次数为较短的信号源的信号个数

 @param signal 信号源1
 @param otherSignal 信号源2
 @return 合并后的新信号源
 */
- (RACSignal *)rac_zipWithSignal:(RACSignal *)signal ofOtherSignal:(RACSignal *)otherSignal;

/**
 混合两个信号源，有混合的先后顺序，即：会将signal源中的信号全部输出后才输出otherSignal，当otherSignal中的信号完全输出完毕后结束（跟- rac_zipSignals的区别在于，- rac_zipSignals是把信号源的信号一一匹配合并，而- rac_concatSignal是把两个信号源的信号组合成一个有顺序的新信号）

 @param signal 信号源1
 @param otherSignal 信号源2
 @return 合并后的新信号源
 */
- (RACSignal *)rac_concatSignal:(RACSignal *)signal ofOtherSignal:(RACSignal *)otherSignal;

////shareSDK
//- (RACSignal *)shareInView:(UIView *)view                          //share的view层
//                   content:(NSString *)content                     //share的内容
//            defaultContent:(NSString *)defaultContent              //默认的share内容
//                     image:(NSString *)image                       //share的图片
//                     title:(NSString *)title                       //share的title
//                       url:(NSString *)url                         //如果share的类型是链接，那么URL表示了该链接
//               description:(NSString *)description                 //share内容的描述
//                 shareList:(NSArray *)shareList                    //share的平台
//                 mediaType:(SSPublishContentMediaType)mediaType;   //share的类型，枚举。


@end
